package me.zhengjie.modules.quartz.task;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.constant.ConstantUtils;
import me.zhengjie.modules.system.domain.CourseMealsOrder;
import me.zhengjie.modules.system.domain.CourseOrder;
import me.zhengjie.modules.system.domain.ExamOrder;
import me.zhengjie.modules.system.domain.IdentityOrder;
import me.zhengjie.modules.system.service.mapstruct.CourseMealsOrderExpMapper;
import me.zhengjie.modules.system.service.mapstruct.CourseOrderExpMapper;
import me.zhengjie.modules.system.service.mapstruct.ExamOrderExpMapper;
import me.zhengjie.modules.system.service.mapstruct.IdentityOrderExpMapper;
import me.zhengjie.modules.web.enums.OrderStatusEnum;
import me.zhengjie.utils.DateUtil;
import me.zhengjie.utils.RedisUtils;
import me.zhengjie.utils.enums.OrderTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class OrderTask {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private CourseOrderExpMapper courseOrderExpMapper;

    @Autowired
    private CourseMealsOrderExpMapper mealsOrderExpMapper;

    @Autowired
    private IdentityOrderExpMapper identityOrderExpMapper;

    @Autowired
    private ExamOrderExpMapper examOrderExpMapper;


    public void expire() {

        log.info("开始执行订单超时取消任务");

        for (OrderTypeEnum value : OrderTypeEnum.values()) {
            Map<Object, Object> expireOrderMap = redisUtils.hmget(ConstantUtils.DefaultTimeRedisKey + "_" + value.getOrderType());
            if (MapUtil.isNotEmpty(expireOrderMap)) {
                log.info("redis中订单数据"+ JSON.toJSONString(expireOrderMap));
            } else {

            }
            if (value.getOrderType().equals(OrderTypeEnum.Exam.getOrderType())) {
                executeExam(0);
            } else if (value.getOrderType().equals(OrderTypeEnum.Report.getOrderType())) {
                executeExam(1);
            } else if (value.getOrderType().equals(OrderTypeEnum.Course.getOrderType())) {
                executeCourse();
            } else if (value.getOrderType().equals(OrderTypeEnum.Meals.getOrderType())) {
                executeMeals();
            } else if (value.getOrderType().equals(OrderTypeEnum.Identity.getOrderType())) {
                executeIdentity();
            }
        }
    }

    private void executeIdentity() {
        log.info("执行身份订单超时过期");
        LambdaQueryWrapper<IdentityOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(IdentityOrder::getPayStatus,ConstantUtils.Order_NoPay).le(IdentityOrder::getExpireTime, DateUtil.TimestampNow());
        List<IdentityOrder> courseOrders = identityOrderExpMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(courseOrders)){
            return;
        }
        courseOrders.parallelStream().forEach(s -> {
            IdentityOrder identityOrder = new IdentityOrder();
            identityOrder.setUpdateTime(DateUtil.TimestampNow());
            identityOrder.setOrderStatus(OrderStatusEnum.TimeOutCancel.getOrderStatus());
            LambdaQueryWrapper<IdentityOrder> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(IdentityOrder::getOrderId,s.getOrderId());
            identityOrderExpMapper.update(identityOrder,wrapper1);
        });
    }

    private void executeMeals() {
        log.info("执行餐费订单超时过期");
        LambdaQueryWrapper<CourseMealsOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseMealsOrder::getPayStatus,ConstantUtils.Order_NoPay).le(CourseMealsOrder::getExpireTime, DateUtil.TimestampNow());
        List<CourseMealsOrder> courseOrders = mealsOrderExpMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(courseOrders)){
            return;
        }
        courseOrders.parallelStream().forEach(s -> {
            CourseMealsOrder courseMealsOrder = new CourseMealsOrder();
            courseMealsOrder.setUpdateTime(DateUtil.TimestampNow());
            courseMealsOrder.setOrderStatus(OrderStatusEnum.TimeOutCancel.getOrderStatus());
            LambdaQueryWrapper<CourseMealsOrder> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(CourseMealsOrder::getOrderId,s.getOrderId());
            mealsOrderExpMapper.update(courseMealsOrder,wrapper1);
        });
    }

    private void executeCourse() {
        log.info("执行课程订单超时过期");
        LambdaQueryWrapper<CourseOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseOrder::getPayStatus,ConstantUtils.Order_NoPay).le(CourseOrder::getExpireTime, DateUtil.TimestampNow());
        List<CourseOrder> courseOrders = courseOrderExpMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(courseOrders)){
            return;
        }
        courseOrders.parallelStream().forEach(s -> {
            CourseOrder courseOrder = new CourseOrder();
            courseOrder.setUpdateTime(DateUtil.TimestampNow());
            courseOrder.setOrderStatus(OrderStatusEnum.TimeOutCancel.getOrderStatus());
            LambdaQueryWrapper<CourseOrder> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(CourseOrder::getOrderId,s.getOrderId());
            courseOrderExpMapper.update(courseOrder,wrapper1);
        });
    }

    private void executeExam(Integer examType) {
        log.info("执行测评订单超时过期");
        LambdaQueryWrapper<ExamOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ExamOrder::getPayStatus,ConstantUtils.Order_NoPay).le(ExamOrder::getExpireTime, DateUtil.TimestampNow()).eq(ExamOrder::getOrderType,examType);
        List<ExamOrder> courseOrders = examOrderExpMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(courseOrders)){
            return;
        }
        courseOrders.parallelStream().forEach(s -> {
            ExamOrder examOrder = new ExamOrder();
            examOrder.setUpdateTime(DateUtil.TimestampNow());
            examOrder.setOrderStatus(OrderStatusEnum.TimeOutCancel.getOrderStatus());
            LambdaQueryWrapper<ExamOrder> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(ExamOrder::getOrderId,s.getOrderId());
            examOrderExpMapper.update(examOrder,wrapper1);
        });
    }
}
